#include "ace/config-lite.h"

#if defined (ACE_HAS_THREADS)

#include "ThreadManager.h"
#include "ThreadWorker.h"

class ThreadWorker : public IWorker<ThreadWorker>
{
public:
	ThreadWorker(IManager<ThreadWorker> *manager): IWorker(manager) { }

protected:
	virtual void process_message(ACE_Message_Block *mb)
	{
		ACE_TRACE ("Worker::process_message");
		int msgId;
		ACE_OS::memcpy(&msgId, mb->rd_ptr(), sizeof(int));
		mb->release ();

		ACE_DEBUG((LM_DEBUG,
			ACE_TEXT("(%t) Started processing message %d\n"),
			msgId));
		ACE_OS::sleep (3);
		ACE_DEBUG((LM_DEBUG,
			ACE_TEXT("(%t) Finished processing message %d\n"),
			msgId));
	}

};


int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ThreadManager<ThreadWorker> tp(20, -1);
  tp.activate();

  // Wait for a moment every time you send a message.
  ACE_Time_Value tv;
  tv.msec(100);
  ACE_Message_Block *mb = 0;
  for (int i = 0; i < 30; i++)
    {
      ACE_NEW_RETURN
        (mb, ACE_Message_Block(sizeof(int)), -1);

      ACE_OS::memcpy (mb->wr_ptr (), &i, sizeof(int));

      ACE_OS::sleep (tv);

      // Add a new work item.
      tp.putq (mb);
    }

  ACE_Thread_Manager::instance ()->wait ();
  return 0;
}

#else
#include "ace/OS_main.h"
#include "ace/OS_NS_stdio.h"

int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_OS::puts (ACE_TEXT ("This example requires threads."));
  return 0;
}

#endif /* ACE_HAS_THREADS */